This invention relates generally to computer systems and more particularly to execution of computer programs on non-native computer system architecture.
As is known in the art, computer systems which generally include a central processing unit, a main memory, and input-output device interconnected by a system bus are used to execute computer programs to perform some useful task. One type of computer program is an operating system which is used to interface the central processing unit to an application program. The aforementioned application program is a program used by a user of the computer system to perform the useful task. The operating system includes all of the software resources needed by the computer system to interface each of the hardware elements, to the computer system as well as to interface the application program to other programs on the computer system.
The application programs can include programs such as spreadsheets, word processors, electronic mail, etc. The application program executes on the computer system under the control of the operating system. The operating system often includes routines or libraries which the application program uses in order to complete its execution.
It is generally known that application programs are written for a particular computer architecture or computer instruction set as well as a particular operating system. Computer architectures are varied, but common architectures include the so-called Alpha.RTM. architecture by Digital Equipment Corporation's assignee of the present invention, the so-called X86 architecture which is based upon the family of X86 microprocessors designed and built by Intel Corp., as well as others such as the Power PC.RTM. architecture designed and built by Motorola, IBM and Apple. Other architectures include the VAX.RTM. architecture by Digital Equipment Corporation and the PA-RISC.RTM. architecture by Hewlett Packard.
Generally, programs written for one architecture are also written for a particular operating system which is supported on the architecture. Thus, for the aforementioned Alpha architecture, the architecture supports the Windows NT.RTM. operating system by Microsoft Corporation, the Open VMS.RTM. operating system by Digital Equipment Corporation, and the UNIX operating system by Digital Equipment Corporation as well as others. Generally application programs written for one architecture and a particular operating system can not directly execute on a different architecture and/or different operating system. New computer architectures are developed in order to provide significant performance improvements for the hardware associated with the architecture. For example, the so-called Alpha.RTM. architecture based upon the 64 bit Alpha microprocessor is a RISC type architecture (Reduced Instruction Set Computer). Presently, versions of the Alpha microprocessor operate at clock speed of 300 MHz. On such an architecture, an application program executes much faster with higher performance and thus provides to a user significant performance advantages.
One drawback to a new architecture, however, is that often application programs written for older architectures can not run directly on the new architecture. This occurs because the instruction sets of the new architecture and the old architecture are different and since different instructions are used in each architecture, the programs are not directly transferable.
While it is desirable for a user to migrate to a new higher performance architecture, one of the most significant drawbacks for a user to migrate to a new architecture is the user's pre-existing investment in software applications as well as data files resulting from application programs run on the old architecture. That is, an architecture which has been in existence for a number of years and used by a large number of users will represent a substantial cumulative financial investment. If that investment is not transferable to a new architecture users will be highly reluctant to migrate to the new architecture.
There are several approaches which have been developed over the years to assist users to migrate from an old architecture to a new architecture. One approach is the so-called "porting approach". With the porting approach a software vendor agrees with the owner of the architecture to take its source code for a particular application program and run the source code through a compiler developed for the new architecture and to perform some sort of checking such as a quality assurance check at the end of the compilation. Thus, with porting the source code of application is converted into an executable image which can run on the new architecture. Porting is a viable solution for many applications. In particular applications involved in the so-called enterprise computing field are excellent candidates for porting since the nature of the program and the nature of the customer are such that there is an expectation of a high level of support from the software vendor as well as from the owner of the architecture.
Another technique commonly employed is so-called "on-line interpretation". In on-line interpretation, a software module called an "interpreter" interprets instructions from the application program written in the non-native instruction set and converts those instructions into instructions or routines which execute on the new architecture. The interpreter thus tests the instructions to determine the resources needed by the instruction and analyzes the instruction to determine the function of the instruction. From this testing the interpreter maps the instruction to a routine that performs the same function only written in instructions executable on the new architecture. After the routine is identified the routine is executed in the computer system to provide the equivalent function called for in the application program written in the non-native instruction set.
A third technique commonly used is a so-called "static translator". In static translator, a software program called a translator receives an instruction in the old architecture, and for each instruction, provides an instruction sequence in the new architecture to accomplish what the original instruction does in the old architecture.
When interpretation or translation is employed to enable a user to execute a non-native application program on a new architecture, the goal is to accurately (transparently?) emulate the architecture for which the application program was initially written so that the user is not aware of any differences between executing the application on the new architecture and executing the application on the architecture it was originally written to execute. Accurate emulation can be difficult to achieve however, when the original architecture relies on a feature of the original architecture not present in the new architecture. An example of such a feature is the condition codes maintained on an X86 machine.
Condition codes are maintained on an X86 machine to provide knowledge of the machine state in the subject architecture to the computer system. Currently, X86 machines utilize six condition codes. These codes are Carry (C), Negative (N), Zero (Z), Overflow (O), Parity (P), and a low nibble carry (A). These condition code bits are modified as a result of the execution of a certain instructions within the X86 instruction set. Subsequent instructions may query the condition code bits to use ore or more of them as input to the instruction, an operand, or one or more of the bits may be used as the basis of a conditional branch.
The instructions that modify the condition codes on an X86 machine fall into five categories which designate which condition code bits are modified as a result of the execution of the individual instructions. In the first category all condition code bits are modified (ALL). The second category of instructions modify all but the Carry bit (ALL.sub.-- BUT.sub.-- C). The third category of instructions modify only the Carry bit (ONLY.sub.-- C) while the fourth category modifies only the Zero bit (ONLY.sub.-- Z). The final category of instructions modify only the Carry and Overflow bits (C.sub.-- AND.sub.-- O). As an application program has no control over the manipulation of the condition codes, i.e. cannot turn off the setting of the bits, to accurately emulate the X86 environment, the emulating environment should also maintain condition codes.
A simplistic approach to emulating condition codes is to maintain, in memory or within the registers of the new architecture, a set of bits which would be used to emulate the X86 condition codes. These bits would be appropriately modified upon execution of each condition code modifying opcode just as the condition codes bits within the X86 architecture are modified.
One problem encountered by this approach however, is that computing the values of the condition codes is computationally intensive. As a result, execution of the application program on the new architecture could appear noticeably slower to the user than it would be on the original architecture.
In addition, condition codes are not necessarily used each time they are altered. That is, execution of a subsequent condition code modifying opcode may overwrite the modifications to the condition codes made by a previous opcode before a subsequent instruction is executed which uses one or more of the condition codes. In a system updating the condition codes after each opcode is executed, a considerable amount of CPU time is wasted which, if avoided, could speed up the execution time of the application program. Moreover, as some instructions only modify a subset of the condition codes it would be an additional waste of CPU time to recompute the current state of each of the condition code bits after each opcode is executed.